﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using PersonaLibrary.Data;
using PersonaLibrary.View.Host;

namespace PersonaLibrary.ViewModel.MainWindowViewModel
{
	internal sealed class ItemsSelectorViewModel : BaseViewModel<ItemsSelectorView>
	{
		private bool _disposed;
		private bool _opened;
		private Predicate<object> _filter;

		private RelayCommand _okCommand;
		private RelayCommand _checkAll;
		private RelayCommand _unCheckAll;

		public RelayCommand CheckAllCommand
		{
			get
			{
				if (_checkAll == null)
					_checkAll = new RelayCommand(x => CheckAll(), x => true);
				return _checkAll;
			}
		}

		public RelayCommand UnCheckAllCommand
		{
			get
			{
				if (_unCheckAll == null)
					_unCheckAll = new RelayCommand(x => UnCheckAll(), x => true);
				return _unCheckAll;
			}
		}

		public RelayCommand OkCommand
		{
			get
			{
				if(_okCommand == null)
					_okCommand = new RelayCommand(x => Ok(), x => true);

				return _okCommand;
			}
		}

		public ObservableCollection<SelectedItem> Collection { private set; get; }

		private void CheckAll()
		{
			foreach (SelectedItem item in Collection)
				item.Selected = true;
		}

		private void UnCheckAll()
		{
			foreach (SelectedItem item in Collection)
				item.Selected = false;
		}

		public bool Opened
		{
			get { return _opened; }
			set
			{
				_opened = value;
				RisePropertyChanged("Opened");
			}
		}

		public Predicate<object> Filter
		{
			get
			{
				return _filter;
			}
			private set
			{
				_filter = value;
				RisePropertyChanged("Filter");
			}
		}

		public void SetCollection(IEnumerable<BaseEntity> entities)
		{
			Collection = new ObservableCollection<SelectedItem>(entities.Select(x => new SelectedItem{ Item = x }));
			RisePropertyChanged("Collection");
		}

		public void ResetFilter()
		{
			Filter = null;
		}

		private void Ok()
		{
			Filter = delegate(object arg)
			         	{
			         		SelectedItem item = Collection.FirstOrDefault(x => x.Item == arg);
							if (item != null)
								return item.Selected;
			         		return false;
			         	};
			View.Hide();
		}

		protected override void OnViewCreated()
		{
			base.OnViewCreated();
			View.Closing += ViewClosing;
		}

		void ViewClosing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			View.Hide();
			e.Cancel = !_disposed;
			Opened = false;
		}

		public override void Dispose()
		{
			_disposed = true;
			base.Dispose();
		}

		public class SelectedItem : INotifyPropertyChanged
		{
			private bool _selected;

			public SelectedItem()
			{
				Selected = true;
			}

			public bool Selected
			{
				set
				{
					_selected = value;
					if(PropertyChanged != null)
						PropertyChanged(this, new PropertyChangedEventArgs("Selected"));
				}
				get
				{
					return _selected;
				}
			}

			public BaseEntity Item { set; get; }

			public event PropertyChangedEventHandler PropertyChanged;
		}
	}
}
